package models

import (
	"errors"
	"fmt"
	"ginclassmates/utils"
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

// 定义一个数据表结构体
type User struct {
	gorm.Model        //gin专用包,里面有：
	Number     string `json:"number" gorm:"unique_index"`           //学号
	Name       string `json:"name" gorm:"type:varchar(50);size:80"` //名字
	Class      string `json:"class" gorm:"type:varchar(20)"`        //班级
	Ip         string `json:"ip" gorm:"type:varchar(20)"`           //IP地址
}

type SignUpRequest struct {
	Name   string `json:"name"`
	Class  string `json:"class"`
	Number string `json:"number"`
}

// 定义一个签到数据表结构体
type Signin_User struct {
	Number      string    `json:"number" gorm:"unique_index"`
	Name        string    `json:"name" gorm:"type:varchar(50)"`  //名字
	Class       string    `json:"class" gorm:"type:varchar(20)"` //班级
	Create_Time time.Time `json:"create_time"`
}

// 定义的存放数据的结构体
type ReadUser struct {
	Number string `json:"number"`
	Name   string `json:"name"`
	Ip     string `json:"ip"`
}

var DB *gorm.DB

// 定义一个初始化User结构体的方法
// 这样使用起来更加方便
func InvokeUser() *User {
	return &User{}
}

// 定义一个方法程序开始时，
// 初始化数据并且连接数据库拿到数据存放在redis中
func InitializeMYSQL() (err error) {
	//dns := "root:123456@tcp(localhost)/ginclassmates?charset=utf8mb4&parseTime=True&loc=Local"
	//创建orm连接池
	DB, err = gorm.Open(mysql.Open(utils.Mysqldns), &gorm.Config{
		//设置日志输出条件
		Logger: logger.Default.LogMode(logger.Info),
	})

	if err != nil {
		return err
	}
	//拿到底层的MySQL连接池DB
	sqldb, err := DB.DB()
	if err != nil {
		return err
	}
	//测试是否连接上数据库
	err = sqldb.Ping()
	if err != nil {
		return err
	}
	//连接上了设置连接池的设置(默认的设置就可以应用于平常的需求)
	//设置连接池的数量时间等
	sqldb.SetMaxOpenConns(10)
	sqldb.SetMaxIdleConns(10)
	sqldb.SetConnMaxIdleTime(time.Hour)
	sqldb.SetConnMaxLifetime(time.Hour)

	//设置好后顺便创建一个数据表
	DB.AutoMigrate(&User{})
	DB.AutoMigrate(&Signin_User{})
	return
}

// 拿出数据库中ip,学号，姓名信息存放在redis中
func UserFind() (user01 []ReadUser, err error) {
	err = DB.Model(&User{}).Select("number", "name", "ip").Find(&user01).Error
	if err != nil {
		return nil, err
	}
	//拿取数据后把这些数据存放再redis中
	for _, v := range user01 {
		//把一个单独拿出来,传入redis方法中处理
		Redisread(v)

	}

	return nil, nil
}

/* // 测试数据库是否能正常添加数据
func (user *User) UserAdd() (err error) {
	user = &User{
		Number: "202120220586",
		Name:   "小明",
		Class:  "云计算2班",
		Ip:     "172.14.1.44",
	}
	err = DB.Create(user).Error
	if err != nil {
		return err
	}
	user = &User{
		Number: "202120220581",
		Name:   "小佳",
		Class:  "云计算2班",
		Ip:     "172.14.1.45",
	}
	err = DB.Create(user).Error
	if err != nil {
		return err
	}
	user = &User{
		Number: "202120220589",
		Name:   "小杰",
		Class:  "云计算2班",
		Ip:     "172.14.1.46",
	}
	err = DB.Create(user).Error
	if err != nil {
		return err
	}
	return
} */

// 将签到的数据存入到数据库中
func Deposit(name, number, class string) (err error) {
	Time := time.Now()
	user := Signin_User{
		Name:        name,
		Number:      number,
		Class:       class,
		Create_Time: Time,
	}
	//判断是否存在重复签到
	var user01 Signin_User
	err = DB.Model(&Signin_User{}).Where("number=? AND create_time>?", number, Time.Add(-24*time.Hour)).First(&user01).Error
	if err == nil {
		return errors.New(user01.Name + "今天已经提交了！~")
	}
	//将新的数据存入数据中
	err = DB.Model(&Signin_User{}).Create(user).Error
	if err != nil {
		return err
	}
	return
}

// 根据学号查询出所有的签到表对应的学号记录
func Query_Signin(number string) (data []Signin_User, err error) {
	err = DB.Model(&Signin_User{}).Where("number=?", number).Find(&data).Error
	if err != nil {
		return nil, err
	}

	return data, nil
}

// 将文件读取的值的数据存入到数据库中
func MYSQL_ExtractData(number, name, ip string) (err error) {
	user := &User{
		Name:   name,
		Number: number,
		Class:  "云计算技术应用2班",
		Ip:     fmt.Sprintf("172.14.1.%v", ip),
	}
	//将新的数据存入数据中
	err = DB.Create(user).Error
	if err != nil {
		return err
	}
	return
}
